VPutSn = Put_Text_B_Length
Put_Text_Zero_Length = Put_Text_Zero_End





Check_Cursor_Over_Building:

 ld h, 0
 ld l, h
 ld (Current_Building), hl

	;This will check to see if the cursor is over a building, including one under
	;construction


 BIT Object_Ready_To_Add, (IY + flag)
 jp nz, Check_Building_On_Top_Of_Solid_Object



 call Find_Tile_On_Map



 ld a, (hl)		;Register A contains the tile we want to check, the tile
			;that the cursor is currently pointing to

 cp 126			;If the cursor is pointing to a building under
			;construction

 RES Cursor_Over_Wrench, (IY + flag + 1)
 jr z, Pre_Draw_Building_Info	;Special care must be taken
				;for a building under construction.
 cp 48				;There are 48 building tiles, 0 to 47.
				;Is the tile 47 or less?

 jr c, _


 ld hl, 55 * 256 + 1
 ld (Money_Amount_Y), hl

 ret


_

 ld hl, Operation_Center 	;Check to see which building the tile
				;corresponds to.  The "Start tile" for the
				;Operation Center is at Operation Center + 1.

 ld b, 16	;16 buildings to check

 ld c, a	;Save the value of the tile
_

 	
 ld e, (hl)	;We save the value of the start tile, and see if the
		;current tile falls with in this range.

 push de

 ld de, 26

 add hl, de
 ld a, (hl)	;Building end tile
 or a
 sbc hl, de

 pop de

 inc hl

 ld d, a
 ld a, c

;See if the value in register a falls between E and D

 inc d

 cp e
 jr c, _
 cp d
 jr c, Draw_Building_Info



_
 
 ld de, 31
 add hl, de

 djnz   --_

 ret

 
Pre_Draw_Building_Info:

 SET Cursor_Over_Wrench, (IY + flag + 1) 



Draw_Building_Info:


 ld de, (63 - 9 - 14) * 256 + 1
 ld (Money_Amount_Y), de

 ld a, (hl)	;Building type

 ld bc, 4	
		
 add hl, bc	

 ld d, (hl)
 inc hl
 ld e, (hl)
 inc hl
 inc hl		;Points to text

 ld (Building_Total_HP), de
 ld d, a

 push hl	;We need to retrieve the building that the tile points to.
		;Save hl for later.

 ld b, 200	;Two hundred buildings to search
 ld hl, Structure_Locations
 ld a,  (TileX)


 ld c, d	;Now Register C contains the building type

 ld d, a

 ld a, (TileY)

 

 ld e, a

_

 push de
 

 ;In case we have the wrong building type

 BIT Cursor_Over_Wrench, (IY + Flag + 1)
 jr z, EmergencyLocalLabel9


 push bc

 ld a, (End_Of_List_Of_Buildings_Under_Construction)
 ld b, a

 push hl

 call Code_To_Call

EmergencyLocalLabel10:

 ld c, (hl)
 cp c
 jr z, EmergencyLocalLabel11

 call IncHL4

 djnz EmergencyLocalLabel10

 pop hl
 pop bc
 


 ld de, 4
 add hl, de
 
 pop de
 djnz -_
 ret

EmergencyLocalLabel11:

 pop hl
 push hl

 inc hl
 inc hl

 call Get_Building_ID_Collision

 

 ld (Structure_Under_Cursor), hl 

 inc hl
 ld e, (hl)
 
 pop hl
 pop bc
 ld c, e

 pop de
 push de




EmergencyLocalLabel9:

 push hl

 call Code_To_Call_2
  pop hl
 jr nz, ++_

 pop de
 push de
 

 ld a, (hl)
 cp d
 jr z, _

 ld a, c
 cp 3		;16 x 16 building
 jr z, ++_
 cp 2		;16 x 32 building
 jr z, ++_ 

 ld a, (hl)
 inc a
 cp d
 jr nz, ++_
_

 inc hl
 ld a, (hl)
 dec hl
 cp e
 jr nz, Continue_Check_Collision_One
 BIT Cursor_Over_Wrench, (IY + flag + 1) 
 jr nz,Building_Under_Cursor_Found_PopDE

 ld (Structure_Under_Cursor), hl
 jr Building_Under_Cursor_Found_PopDE

Continue_Check_Collision_One:

 call Code_To_Call_3
 jr z, _
 cp 1
 jr z, _

 ld a, d
 inc a
 cp e
 jr nz, _

 BIT Cursor_Over_Wrench, (IY + flag + 1) 
 jr nz,Building_Under_Cursor_Found_PopDE

 ld (Structure_Under_Cursor), hl
 jr Building_Under_Cursor_Found_PopDE

_

 call IncHL4

 pop de
 djnz ---_

 ret

Building_Under_Cursor_Found_PopDE:

 pop de

Building_Under_Cursor_Found

 push hl	;Save where the building is so we can retrieve the HP after
 		;putting the info box on the screen

 ld hl, InfoBox
 ld de, plotsscreen + (49*12)
 ld bc, 15*12
 ldir

_ 


 pop hl		;hl points to the beginning of the building.  Retrieve the HP.

 push hl


 inc hl
 inc hl		;Get HP

 ld a, (hl)
 and %00001111
 ld d, a
 ld a, (hl)	;We need to see if the building is a refinery.

 inc hl
 ld e, (hl)

 
 ld hl, 51 * 256 + 2
 ld (penCol), hl 



 ;We needed to go through all this to get the HP.  However, it is
 ;now very possible that we should not display the name of the building on the first
 ;line of the text box.  We display the name if the builidng is being constructed or if the building
 ;is under normal circumstances.  If the building is CONSTRUCTING something, we display (in the first
 ;line) what the building is constructng.


 pop bc
 pop hl

 push de	;Saves the HP

 BIT Cursor_Over_Wrench, (IY + flag + 1) 
 jr nz, EmergencyLocalLabel13

 ld b, h		;Save the value of HL, JUST IN CASE we need to display the building name
 ld c, l		;rather than what is being constructed

 ;Is this a refinery constructing a processing unit?  It requires special code to see if it
 ;actually is.

 and %11110000
 cp $50
 jr nz, _


 call _Get_To_Structure_Tags_From_Structure_Locations

 ;HL contains the data for the partictual refinery.  If the first byte is greater than
 ;the second byte, a processing unit is being built.

 ld a, (hl)

 inc hl

 cp (hl)

 ;If the two bytes are equal, the cursor is simply pointing to a normally-operating refinery
 
 jr nz, Refinery_Building_Processing_Unit

 ld h, b
 ld l, c

 jr _

Refinery_Building_Processing_Unit:


;Stores the number of PUs qued by taking the number of processing units the player
;WANTS to have and subtracting the number actually built

 ld e, (hl)
 dec hl
 ld a, (hl)

 sub e

 ld d, 0
 ld e, a	

 push de



 ld hl, cleartext
 ld de, ASCIINumber
 ld bc, 6
 ldir

 pop de


 ld hl, 51 * 256 + 80
 ld (penCol), hl 

 call bintobcd16

 ld hl, ASCIINumber

 Call Put_Text_Zero_End

 ld hl, 51 * 256 + 2
 ld (penCol), hl

 ld hl, Text_Building_Processing_Unit
 ld b, 15
 jr ++_
 


EmergencyLocalLabel13:

 ld hl, (Structure_Under_Cursor)

 ld de, 5
 add hl, de

 ld d, (hl)
 inc hl
 ld e, (hl)
 inc hl
 inc hl

 ld (Building_Total_HP), de
 

_




 ld b, 18

_
 call VPutSN



 ld hl, 57*256+2		;Friendly or not?
 ld (penCol), hl
 ld b, 8
 ld hl, Friendly_Unit
 call VPutSN

 ld hl, 57*256+60		;"HP:"
 ld (penCol), hl
 ld b, 3
 ld hl, HP_Text
 call VPutSN


 ;Now display the hp

_

Draw_Different_HP:

 ld hl, zerotext
 ld de, ASCIINumber
 ld bc, 6
 ldir
 pop de
 push de


 call bintobcd16
 ld hl, 57*256+72		
 ld (penCol), hl
 
 ld hl, ASCIINumber

 Call Put_Text_Zero_End
 
 pop hl
 ex de, hl
 
 ld hl, (Structure_Under_Cursor)
 inc hl
 inc hl



 ld a, (hl)
 and %11110000
 
 cp $50
 jp z, +_


;We need to see if a building is constructing some units.  If
;this is the case, we need the health bar to be a progress bar,
;and we need to display a list of units under construction.

 cp $80
 jp c, EmergencyLocalLabel17
 cp $F0
 jp nc, EmergencyLocalLabel17


;Start by displaying a list of units are
;on que.  The unit pictures are stored in the font,
;so we turn the 3 units into three characters of text.

 call _Get_To_Structure_Tags_From_Structure_Locations 

 inc hl
 ld a, (hl)
 and %00001111
 jp z, EmergencyLocalLabel17
 dec hl

 ld d, h
 ld e, l


EmergencyLocalLabel18

 ld hl, Text_Buffer

 ld a, (de)
 and %11110000

 rrca \ rrca \ rrca \ rrca
 ld c, a	;Save the ship being constructed.
 add a, $25

 ld (hl), a
 inc hl
 ld a, (de)
 and %00001111
 add a, $25

 ld (hl), a
 inc hl
 inc de
 ld a, (de)
 and %11110000
 rrca \ rrca \ rrca \ rrca
 add a, $25
 ld (hl), a
 
 ld hl, 51 * 256 + 72
 ld (penCol), hl 

 push de
 push bc

 ld hl, Text_Buffer
 ld b, 3
 
 call Put_Text_B_Length
 
 pop bc
 pop hl
 
;Find the building constructing the unit.

 inc hl
 ld d, (hl)
 inc hl
 ld e, (hl)

 ex de, hl
 inc hl
 ld d, (hl)
 inc hl
 ld e, (hl)

 push de




 ld a, c	;Register A contains the ship being
		;built

 ld de, NumberOfBytesPerShip

 call Multiply_DE_By_A

 
 ld de, Unit_Scouter

 add hl, de


;Get the total build time of the unit

	ld bc, 7
	add hl, bc

	ld d, (hl)
	inc hl
	ld e, (hl)

 pop hl
 ex de, hl

;Fixes a bug
;---------------------------------

 ld a, d
 or e
 jr nz, EmergencyLocalLabel21

 ld de, (Building_Emergency_HP)


EmergencyLocalLabel21:

 ld (Building_Emergency_HP), de

;--------------------------------

 ld (Building_Total_HP), hl

 or a
 sbc hl, de
 ex de, hl
 

EmergencyLocalLabel17:

 ex de, hl
 call Multiply_HP_By_32



 ld de, (Building_Total_HP)
 jr ++_

 ;IF a processing unit is being constructed, we need to adjust the Total HP
 ;so that the correct progress bar displays correctly.

_
 ex de, hl
 push af
 push hl
 

 call _Get_To_Structure_Tags_From_Structure_Locations

 ;Display the number of processing units the building has

 inc hl

 ld a, (hl)
 dec hl
 cp (hl)

 jr nz, No_Draw_Number_Of_PUs

 push hl



 ld hl, zerotext
 ld de, ASCIINumber
 ld bc, 6
 ldir

 ld d, 0
 ld e, a

 call bintobcd16
 ld hl, 51*256+61		
 ld (penCol), hl

 ld hl, ASCIINumber

 call Put_Text_Zero_End
 pop hl

No_Draw_Number_Of_PUs:


 ;Now HL points to the number of processing units we WANT to have (but might not have)

 ld a, (hl)
 or a

 jr nz, EmergencyLocalLabel16



 pop hl
 pop af


 call Multiply_HP_By_32

 ld de, (Building_Total_HP)


 jr _

EmergencyLocalLabel16:

 inc hl ;HL points to the number of processing units we actually have.  We need this to display
	;the progress bar for health correctly.

 cp (hl)	;If no processing units are being built, we display the total HP of the current processing unit.
		
 
 jr nz, EmergencyLocalLabel15


 inc hl		
 ld a, (hl)

 pop hl
 ld h, 0
 ld l, a

 pop af

 call Multiply_HP_By_32

 ld de, 120

 jr +_



EmergencyLocalLabel15:	;For a processing unit that is being built


 ld a, (hl)
 inc a

 ld de, 120
 call Multiply_DE_By_A
 
 ex de, hl

 or a
 pop hl
 sbc hl, de
 
 ld de, 120

 pop af

 call Multiply_HP_By_32
 


_

 call Divide_AC_By_DE

 ld d, a
 ld e, c

 ld a, 96


 call Multiply_DE_By_A

 ex de, hl

 srl d \ rr e
 srl d \ rr e
 srl d \ rr e
 srl d \ rr e
 srl d \ rr e




 ld d, e
 ld e, 0
 
 push de

 ld a, 12
 ld (Sprite_Width), a
 ld b, 5

 ld a, 0
 ld l, 0

 ld ix, Progress_Health_Bar
 call Put_Sprite_Overwrite

 pop de

 ld a, d
 and %11111000
 rrca \ rrca \ rrca
 ld c, a
 ld a, 12
 sub c

 ld b, 5
 ld c, a

 ld ix, Progress_Bar_Clear
 ld iy, Progress_Bar_Clear

 call LargeClippedSprite

 ld iy, flags
 ret

ClearText:

 .db "//////"


Divide_AC_By_DE:
   ld	hl, 0
   ld	b, 16

_loop:
   scf \ rl c

   rla
   adc	hl, hl
   sbc	hl, de
   jr	nc, $+4
   add	hl, de
   dec	c
   
   djnz	_loop
   
   ret

Progress_Health_Bar:

	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %00110000,%11000011,%00001100,%00110000,%11000011,%00001100,%00110000,%11000011,%00001100,%00110000,%11000011,%00001101
	.db %01100001,%10000110,%00011000,%01100001,%10000110,%00011000,%01100001,%10000110,%00011000,%01100001,%10000110,%00011001
	.db %11000011,%00001100,%00110000,%11000011,%00001100,%00110000,%11000011,%00001100,%00110000,%11000011,%00001100,%00110001
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111

Progress_Bar_Clear:

	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111
	.db %11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111,%11111111


Get_Building_ID_Collision:

 ld a, (hl)

 and %11110000
 rra \ rra \ rra \ rra
 ld e, a
 ld d, 0
 ld a, 32
 Call Multiply_DE_By_A
 ex de, hl
 ld hl, Operation_Center
 add hl, de

 ret


Check_Building_On_Top_Of_Solid_Object:


;When deciding where to put a building, this sub will
;determine if one would place a building on 
;a solid object, such as a rock, tree or another building


;Register A will hold the building that the user
;is currently deciding where to place

	ld de, 55 * 256 + 1
 	ld (Money_Amount_Y), de

	ld a, (BuildingSelected)

;We need to know how many tiles the building has,
;so that we know how many places to check for solid objects
;under the building.  We find the building being built,
;and retrive whether it's 16 x 16, 32 x 32, etc.

	ld de, 32
	
	call Multiply_DE_By_A

	ld de, Operation_Center
	add hl, de

	inc hl	;HL now points to the building type

	ld c, (hl)	;Register C contains the building
			;type.  I used register C
			;because it's traditional in this
			;program, the reason being that
			;it's partner (B), DE and HL
			;are often tied up.

;We need to adjust the values of the cursor to
;quickly detect collision.  The program will
;store the values temporarily into IX.

	ld ix, (Select_Cursor_X)

;Depending on the building type, we will need to check
;for collision from several tiles.  We will use
;DJNZ and register for B.  Using C, which contains the
;building type, we find an appropriate value for register
;B.

	

	ld a, c
	or a
	jr nz, _
	ld b, 4
	jr +++_
_
	cp 3
	jr nz, _
	ld b, 1
	jr ++_

_
	ld b, 2


_

Check_Tile_Under_Cursor_For_Collision:
	



	;Now that we know how big the building is,
	;look at where the cursor is, and see if any
	;collidable tiles fall under the building.

	;We look at the tile under the cursor, and in some
	;cases, surrounding tiles.

	push bc
 	call Find_Tile_On_Map

	;HL contains the tile we want to check for
	;solidity

	
	ld d, h
	ld e, l

	ld a, (hl)	;In case we need to check collision
			;for refineries (and thus require special code),
			;we save the value for the current tile.


	ld bc, MapData + 2
	or a
	sbc hl, bc

	ld b, a

	;Refineries can only be built on top of crystal deposits.  We
	;use a special collision function to test for refineries.

	ld a, (BuildingSelected)
	cp 5		;Refinery
	jr nz, _

	ld a, b

;This part will be optimized later, but right now, crystals are here, there
;and everywhere in the tileset

	cp 93
	jr z, Building_Can_Be_Placed
	cp 94
	jr z, Building_Can_Be_Placed
	cp 109
	jr z, Building_Can_Be_Placed
	cp 110
	jr z, Building_Can_Be_Placed
	jr Building_Cannot_Be_Placed


_
	

	;Divide HL by 2, and store the value into DE.
	;This will get to the proper tile conditions.

	srl h \ rr l
	
	ld bc, MapTileConditions
	add hl, bc

	pop bc


	ex de, hl	




	;Now hl points to the tile that the cursor 
	;is over.  DE points to the pair of tiles,
	;one of which the tile in hl points to.

	;Find out if the tile hl points to is
	;refered to in the first nibble of DE or the
	;last nibble of DE

	BIT 0, l
	
	jr nz, _
	jr Check_First_Pair_Tile_Over_Building
	jr ++_

_	
	jr Check_Second_Pair_Tile_Over_Building

_

Check_Solid_Continue:

	dec b


	;If b = 0, all tiles have passed,
	;and the building can be placed in the spot.

	jr z, Building_Can_Be_Placed

	ld a, b

	cp 3
	jr z, Adjust_Cursor_Check_Solid_For_32x32

	cp 2
	jr z, Adjust_Cursor_Check_Solid_For_16x32

;B = 1
	ld a, c
	cp 1
	jr z, Adjust_Cursor_Check_Solid_For_32x32
	or a
	jr z, Adjust_Cursor_Check_Solid_For_32x32


	
	;We adjust the cursor position to search
	;the other tiles, seeing if collision can occur.
	;We add H to Cursor_X and L to Cursor_Y.

Adjust_Cursor_Check_Solid_Other:

	ld h, 0
	ld l,16
	jr Change_Cursor_To_Check_Solid	


Adjust_Cursor_Check_Solid_For_32x32:

	
	ld h, 16
	ld l, 0
	jr Change_Cursor_To_Check_Solid

Adjust_Cursor_Check_Solid_For_16x32:

	ld l, 16
	ld h, -16

Change_Cursor_To_Check_Solid:

	ld a, (Cursor_X)
	add a, h
	ld (Cursor_X), a

	ld a, (Cursor_Y)
	add a, l
	ld (Cursor_Y), a

	jr Check_Tile_Under_Cursor_For_Collision


Check_First_Pair_Tile_Over_Building:


	ld a, (de)

	and %00010000

	jr z, Check_Solid_Continue

;Since the building cannot be placed, let the player
;know that by drawng a building in inverse colors.

	jr Building_Cannot_Be_Placed



Check_Second_Pair_Tile_Over_Building:


	ld a, (de)

	and %00000001

	jr z, Check_Solid_Continue

;Since the building cannot be placed, let the player
;know that by drawng a building in inverse colors.

Building_Cannot_Be_Placed:



	ld (Select_Cursor_X), IX

	BIT Building_Over_Solid_Object, (IY + flag + 2)
	jr nz, _

	SET Building_Over_Solid_Object, (IY + flag + 2)
	call Invert_Building_Cursor

_
	ret

Building_Can_Be_Placed:



	ld (Select_Cursor_X), IX

	BIT Building_Over_Solid_Object, (IY + flag + 2)
	jr z, _

	RES Building_Over_Solid_Object, (IY + flag + 2)
	call Invert_Building_Cursor

_
	ret


Invert_Building_Cursor:

	ld b, 128	;The cursor buffer is only 128 bytes.
			;We need to invert all those bytes.

	ld hl, Cursor_Building_Space + 3

_

	ld a, (hl)
	cpl
	ld (hl), a
	inc hl
	djnz -_
	
	ret



Code_To_Call:

 or a
 ld de, Structure_Locations
 sbc hl, de
 ld a, l
 srl h \ rra
 srl h \ rra

 ld hl, List_Of_Buildings_Under_Construction
 
 ret

IncHL4:

 inc hl
 inc hl
 inc hl
 inc hl
 ret

Code_To_Call_2:

 inc hl
 inc hl
 call Get_Building_ID_Collision

 inc hl
 ld a, c
 cp (hl)


 ret

Code_To_Call_3:

 ld d, a
 ld a, c
 cp 3

 ret




_Get_To_Structure_Tags_From_Structure_Locations:

 ld hl, (Current_Building) 

 ld de, Structure_Tags -Structure_Locations
 
 add hl, de

 ret
